<!DOCTYPE html>
<html lang="zh-CN">
    <head>
    <meta charset="utf-8">

    

    <!-- 渲染优化 -->
    <meta name="renderer" content="webkit">
    <meta name="force-rendering" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="HandheldFriendly" content="True" >
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    <!--icon-->

    
        <link rel="shortcut icon" href="https://s1.imgpp.com/2022/01/28/owl.png">
    
    
    
    
    


    <!-- meta -->


<title>电商后台管理系统笔记 | 猫头鹰的BLOG</title>


    <meta name="keywords" content="电商, 后台管理, 猫头鹰的博客">




    <!-- OpenGraph -->
 
    <meta name="description" content="css小技巧让容器的宽高沾满全屏 一般给容器height：100%失效原因是：html,body,#app这些容器没撑开  html,body,#app&amp;#123; 	height:100px; &amp;#125;  让盒子水平垂直居中 适用于登陆注册卡片水平垂直居中  &gt; transform:translate(-50%,-50%):向左平移自身的50%，向上平移自身的50% #box&amp;#123">
<meta property="og:type" content="article">
<meta property="og:title" content="电商后台管理系统笔记">
<meta property="og:url" content="http://example.com/2022/04/21/%E7%94%B5%E5%95%86%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F2.0/index.html">
<meta property="og:site_name" content="猫头鹰的BLOG">
<meta property="og:description" content="css小技巧让容器的宽高沾满全屏 一般给容器height：100%失效原因是：html,body,#app这些容器没撑开  html,body,#app&amp;#123; 	height:100px; &amp;#125;  让盒子水平垂直居中 适用于登陆注册卡片水平垂直居中  &gt; transform:translate(-50%,-50%):向左平移自身的50%，向上平移自身的50% #box&amp;#123">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://images.pexels.com/photos/11739436/pexels-photo-11739436.jpeg?cs=srgb&dl=pexels-%E5%85%89%E6%9B%A6-%E5%88%98-11739436.jpg&fm=jpg">
<meta property="article:published_time" content="2022-04-21T13:59:59.000Z">
<meta property="article:modified_time" content="2022-04-30T13:57:25.608Z">
<meta property="article:author" content="张程">
<meta property="article:tag" content="电商">
<meta property="article:tag" content="后台管理">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://images.pexels.com/photos/11739436/pexels-photo-11739436.jpeg?cs=srgb&dl=pexels-%E5%85%89%E6%9B%A6-%E5%88%98-11739436.jpg&fm=jpg">


    
<link rel="stylesheet" href="/css/style/main.css">
 

    
    
    
        <link rel="stylesheet" id="hl-default-theme" href="https://cdn.jsdelivr.net/npm/highlight.js@10.1.2/styles/arduino-light.min.css" media="none" >
        
            <link rel="stylesheet" id="hl-dark-theme" href="https://cdn.jsdelivr.net/npm/highlight.js@10.1.2/styles/obsidian.min.css" media="none">
        
    

    

    
    
<link rel="stylesheet" href="/css/style/dark.css">

    
<script src="/js/darkmode.js"></script>



     
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
 

    <!-- custom head -->

<meta name="generator" content="Hexo 6.0.0"></head>

    <body>
        <div id="app">
            <header class="header">
    <div class="header__left">
        <a href="/" class="button">
            <span class="logo__text">猫头鹰</span>
        </a>
    </div>
    <div class="header__right">
        
            <div class="navbar__menus">
                
                    <a href="/" class="navbar-menu button">首页</a>
                
                    <a href="/tags/" class="navbar-menu button">标签</a>
                
                    <a href="/categories/" class="navbar-menu button">分类</a>
                
                    <a href="/archives/" class="navbar-menu button">归档</a>
                
            </div>
        
        
        
    <a href="/search/" id="btn-search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="24" height="24" fill="currentColor" stroke="currentColor" stroke-width="32"><path d="M192 448c0-141.152 114.848-256 256-256s256 114.848 256 256-114.848 256-256 256-256-114.848-256-256z m710.624 409.376l-206.88-206.88A318.784 318.784 0 0 0 768 448c0-176.736-143.264-320-320-320S128 271.264 128 448s143.264 320 320 320a318.784 318.784 0 0 0 202.496-72.256l206.88 206.88 45.248-45.248z"></path></svg>
    </a>


        
        
    <a href="javaScript:void(0);" id="btn-toggle-dark">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
    </a>


        
            <a class="dropdown-icon button" id="btn-dropdown" tabindex="0"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width='24' height='24' fill="none" stroke="currentColor" stroke-width="0.7" stroke-linecap="round" stroke-linejoin="round"><path fill="currentColor" d="M3.314,4.8h13.372c0.41,0,0.743-0.333,0.743-0.743c0-0.41-0.333-0.743-0.743-0.743H3.314c-0.41,0-0.743,0.333-0.743,0.743C2.571,4.467,2.904,4.8,3.314,4.8z M16.686,15.2H3.314c-0.41,0-0.743,0.333-0.743,0.743s0.333,0.743,0.743,0.743h13.372c0.41,0,0.743-0.333,0.743-0.743S17.096,15.2,16.686,15.2z M16.686,9.257H3.314c-0.41,0-0.743,0.333-0.743,0.743s0.333,0.743,0.743,0.743h13.372c0.41,0,0.743-0.333,0.743-0.743S17.096,9.257,16.686,9.257z"></path></svg></a>
            <div class="dropdown-menus" id="dropdown-menus">
                
                    <a href="/" class="dropdown-menu button">首页</a>
                
                    <a href="/tags/" class="dropdown-menu button">标签</a>
                
                    <a href="/categories/" class="dropdown-menu button">分类</a>
                
                    <a href="/archives/" class="dropdown-menu button">归档</a>
                
            </div>
        
    </div>
</header>


            <main class="main">
    

<div class="post-title">
    <h1 class="post-title__text">
        电商后台管理系统笔记
    </h1>
    <div class="post-title__meta">
        <a href="/archives/2022/04/" class="post-meta__date button">2022-04-21</a>
        
    <span class="separate-dot"></span><a href="/categories/%E7%AC%94%E8%AE%B0/" class="button">笔记</a>

 
        
    
     
    <span id="busuanzi_container_page_pv" hidden>
        <span class="separate-dot"></span>
        <span></span>
        <span id="busuanzi_value_page_pv"></span>
        <span>次观看</span>
    </span>



 

 
    </div>
</div>



<article class="post content-card">
    <div class="post__header">
    
        <div class="post-thumbnail lazy" data-bg="https://images.pexels.com/photos/11739436/pexels-photo-11739436.jpeg?cs=srgb&amp;dl=pexels-%E5%85%89%E6%9B%A6-%E5%88%98-11739436.jpg&amp;fm=jpg"></div>
    
</div>
    <div class="post__content">
        <h2 id="css小技巧"><a href="#css小技巧" class="headerlink" title="css小技巧"></a>css小技巧</h2><h4 id="让容器的宽高沾满全屏"><a href="#让容器的宽高沾满全屏" class="headerlink" title="让容器的宽高沾满全屏"></a>让容器的宽高沾满全屏</h4><blockquote>
<p>一般给容器height：100%失效原因是：html,body,#app这些容器没撑开</p>
</blockquote>
<pre><code class="hljs css"><span class="hljs-selector-tag">html</span>,<span class="hljs-selector-tag">body</span>,<span class="hljs-selector-id">#app</span>&#123;
	<span class="hljs-attribute">height</span>:<span class="hljs-number">100px</span>;
&#125;</code></pre>

<h4 id="让盒子水平垂直居中"><a href="#让盒子水平垂直居中" class="headerlink" title="让盒子水平垂直居中"></a>让盒子水平垂直居中</h4><blockquote>
<p>适用于登陆注册卡片水平垂直居中</p>
</blockquote>
<pre><code class="hljs css">&gt; <span class="hljs-attribute">transform</span>:<span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>,-<span class="hljs-number">50%</span>):向左平移自身的<span class="hljs-number">50%</span>，向上平移自身的<span class="hljs-number">50%</span>
#box&#123;
	position:absolute;
    <span class="hljs-attribute">left</span>:<span class="hljs-number">50%</span>;
    <span class="hljs-attribute">top</span>:<span class="hljs-number">50%</span>;
    <span class="hljs-attribute">transform</span>:<span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>,-<span class="hljs-number">50%</span>)
&#125;</code></pre>

<h4 id="头部样式"><a href="#头部样式" class="headerlink" title="头部样式"></a>头部样式</h4><blockquote>
<p>justify-content 主轴对其方式<br>align-items 交叉轴对其方式<br>子元素行内元素和块级元素都适用</p>
</blockquote>
<pre><code class="hljs css"><span class="hljs-selector-tag">header</span>&#123;
	<span class="hljs-attribute">display</span>:flex;
	<span class="hljs-attribute">justify-content</span>: space-between;
	<span class="hljs-attribute">align-items</span>: center;
&#125;</code></pre>

<h4 id="解决菜单栏右边突出问题"><a href="#解决菜单栏右边突出问题" class="headerlink" title="解决菜单栏右边突出问题"></a>解决菜单栏右边突出问题</h4><blockquote>
<p>菜单栏右边框默认：1px，直接取消</p>
</blockquote>
<pre><code class="hljs css"><span class="hljs-selector-class">.el-menu</span>&#123;
  <span class="hljs-attribute">border-right</span>: none;
&#125;</code></pre>

<h2 id="登录及导航守卫"><a href="#登录及导航守卫" class="headerlink" title="登录及导航守卫"></a>登录及导航守卫</h2><blockquote>
<p>思路</p>
</blockquote>
<ol>
<li>创建登录组件</li>
<li>进行数据绑定</li>
<li>表单重置</li>
<li>提交时进行预验证</li>
<li>预验证通过后，进行axios请求登录</li>
<li>登录成功后返回token，将其保存到sessionStorage和vuex中</li>
<li>通过编程式导航跳转到后台主页<blockquote>
<p>为什么不用localStorage?</p>
</blockquote>
</li>
</ol>
<ul>
<li>localStorage是本地持久化储存，再次打开网站时，token还会存在，不适合token储存</li>
<li>sessionStorage本地会话储存，token只在这次会话中</li>
</ul>
<h4 id="导航守卫"><a href="#导航守卫" class="headerlink" title="导航守卫"></a>导航守卫</h4><blockquote>
<p>用的是全局前置导航守卫：beforeEach<br>我的理解是：在每个路由导航之前，进行拦截<br>导航守卫分三种情况：</p>
</blockquote>
<ul>
<li>去登录，直接放行</li>
<li>不去登录，没token，重定向到登录</li>
<li>不去登录，有token，直接放行<pre><code class="hljs javascript">router.beforeEach(<span class="hljs-function">(<span class="hljs-params">to,<span class="hljs-keyword">from</span>,next</span>)=&gt;</span>&#123;
	<span class="hljs-keyword">if</span>(to.path===<span class="hljs-string">&#x27;/login&#x27;</span>) <span class="hljs-keyword">return</span> next()
	<span class="hljs-keyword">const</span> token=<span class="hljs-built_in">window</span>.ssesionStorage.getItem(<span class="hljs-string">&#x27;token&#x27;</span>)
	<span class="hljs-keyword">if</span>(!token) <span class="hljs-keyword">return</span> next(<span class="hljs-string">&#x27;/login&#x27;</span>)
	next()
&#125;)</code></pre>
<blockquote>
<p>注意：token常量不能放在函数外面，但凡有一次登录成功，ssesionStorage中保存了token<br>在函数外面的token也会保存token，一直会在内存里，当第二次路由导航时，无ssesionStorage<br>有无token，都会放行</p>
</blockquote>
</li>
</ul>
<h2 id="对elementui进行二次封装"><a href="#对elementui进行二次封装" class="headerlink" title="对elementui进行二次封装"></a>对elementui进行二次封装</h2><h4 id="侧边栏封装"><a href="#侧边栏封装" class="headerlink" title="侧边栏封装"></a>侧边栏封装</h4><blockquote>
<p>模板<br>index 一定要配置唯一标识，不然激活文字颜色不能用，很多报错<br>可以给aside侧边栏一个width：auto,让他随子元素的大小而变化</p>
</blockquote>
<pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 菜单 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">el-menu</span></span>
<span class="hljs-tag"><span class="hljs-attr">default-active</span>=<span class="hljs-string">&quot;默认激活菜单项&quot;</span></span>
<span class="hljs-tag"><span class="hljs-attr">unique-opened</span>=<span class="hljs-string">“是否只保持一个子菜单的展开”</span></span>
<span class="hljs-tag"><span class="hljs-attr">:router</span>=<span class="hljs-string">&quot;开启路由，默认一菜单项的index属性为路径&quot;</span></span>
<span class="hljs-tag"><span class="hljs-attr">:collapse</span>=<span class="hljs-string">&quot;水平展开和折叠&quot;</span></span>
<span class="hljs-tag"><span class="hljs-attr">:collapse-transition</span>=<span class="hljs-string">&quot;是否开启折叠动画&quot;</span></span>
<span class="hljs-tag">&gt;</span>
<span class="hljs-comment">&lt;!-- 一级菜单 --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">el-submenu</span> <span class="hljs-attr">:index</span>=<span class="hljs-string">&quot;一级菜单唯一标识&quot;</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- 一级菜单模板区域 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;title&quot;</span>&gt;</span>
      <span class="hljs-comment">&lt;!-- 图标 --&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">i</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
      <span class="hljs-comment">&lt;!-- 文字 --&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- 二级菜单 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-menu-item</span></span>
<span class="hljs-tag">      <span class="hljs-attr">:index</span>=<span class="hljs-string">&quot;二级菜单唯一标识&quot;</span></span>
<span class="hljs-tag">      <span class="hljs-attr">:route</span>=<span class="hljs-string">&quot;给每个菜单项配置路由路径&quot;</span></span>
<span class="hljs-tag">      &gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&quot;title&quot;</span>&gt;</span>
          <span class="hljs-comment">&lt;!-- 图标 --&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">i</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
          <span class="hljs-comment">&lt;!-- 文字 --&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">el-menu-item</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">el-submenu</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">el-menu</span>&gt;</span></code></pre>

<blockquote>
<p>一级菜单添加图标</p>
</blockquote>
<pre><code class="hljs javascript"><span class="hljs-comment">// data中创建iicon对象，v-for循环一级菜单</span>
<span class="hljs-comment">// 用：class=&quot;icon[item.id]&quot;</span>
<span class="hljs-attr">icon</span>: &#123;
    <span class="hljs-number">125</span>: <span class="hljs-string">&#x27;el-icon-user-solid&#x27;</span>,
    <span class="hljs-number">103</span>: <span class="hljs-string">&#x27;el-icon-s-check&#x27;</span>,
    <span class="hljs-number">101</span>: <span class="hljs-string">&#x27;el-icon-s-shop&#x27;</span>,
    <span class="hljs-number">102</span>: <span class="hljs-string">&#x27;el-icon-s-order&#x27;</span>,
    <span class="hljs-number">145</span>: <span class="hljs-string">&#x27;el-icon-s-marketing&#x27;</span>
&#125;</code></pre>

<h4 id="表格的封装"><a href="#表格的封装" class="headerlink" title="表格的封装"></a>表格的封装</h4><blockquote>
<p>结构由el-table和el-table-column组成，el-table-column存在数据的用v-for渲染</p>
</blockquote>
<ul>
<li>我一般是这样渲染的</li>
<li>注意prop一定要对应数据源中的字段<pre><code class="hljs vue">&lt;el-table-column v-for=&quot;(col,index) in colArray&quot;
	:prop=&quot;col.prop&quot;
    :key=&quot;index&quot;
    :width=&quot;col.width&quot;
    :label=&quot;col.label&quot;
&gt;
&lt;/el-table-column&gt;
colArray: [
    &#123;
        prop: &#x27;username&#x27;,
        label: &#x27;姓名&#x27;,
        width: &#x27;130px&#x27;
    &#125;,
    &#123;
        prop: &#x27;email&#x27;
        label: &#x27;邮箱&#x27;,
        width: &#x27;220px&#x27;
    &#125;
]</code></pre>
<blockquote>
<p>el-table的属性</p>
</blockquote>
</li>
<li>data 数据源<blockquote>
<p>el-table-column的属性</p>
</blockquote>
</li>
<li>label 每列的列头</li>
<li>prop 数据源中的某个字段</li>
</ul>
<h4 id="分页封装"><a href="#分页封装" class="headerlink" title="分页封装"></a>分页封装</h4><blockquote>
<p>属性</p>
</blockquote>
<ul>
<li>page-size 每页大小</li>
<li>current-page 当前页数</li>
<li>total 总条数</li>
<li>current-change 当前页数改变</li>
<li>size-change 每页大小改变</li>
<li>page-sizes 每页大小数组</li>
</ul>
<blockquote>
<p>关于封装了组件，父组件怎么调用其中方法</p>
</blockquote>
<ul>
<li>子组件绑定一个ref，父组件声明子组件时，也绑定一个ref</li>
<li>调用：this.$refs.xx.$refs.xx</li>
</ul>
<blockquote>
<p>封装的组件</p>
</blockquote>
<pre><code class="hljs vue">&lt;template&gt;
  &lt;el-pagination
    @size-change=&quot;handleSizeChange&quot;
    @current-change=&quot;handleCurrentChange&quot;
    :current-page=&quot;pagenum&quot;
    :page-sizes=&quot;pagesizes&quot;
    :page-size=&quot;pagesize&quot;
    layout=&quot;total, sizes, prev, pager, next, jumper&quot;
    :total=&quot;total&quot;&gt;
  &lt;/el-pagination&gt;
&lt;/template&gt;

&lt;script&gt;
export default &#123;
  name: &#x27;Pagination&#x27;,
  props: &#123;
    pagenum: Number,
    pagesize: Number,
    total: Number,
    pagesizes: Array,
    handleSizeChange: Function,
    handleCurrentChange: Function
  &#125;
&#125;
&lt;/script&gt;</code></pre>

<blockquote>
<p>父组件</p>
</blockquote>
<pre><code class="hljs vue">&lt;template&gt;
  &lt;Pagination
  :pagenum=&quot;queryObj.pagenum&quot;
  :pagesize=&quot;queryObj.pagesize&quot;
  :total=&quot;total&quot;
  :pagesizes=&quot;pagesizes&quot;
  :handleSizeChange=&quot;handleSizeChange&quot;
  :handleCurrentChange=&quot;handleCurrentChange&quot;
  /&gt;
&lt;/template&gt;
&lt;script&gt;
export default &#123;
  data () &#123;
    return &#123;
      queryObj: &#123;
        query: &#x27;&#x27;,
        pagenum: 1,
        pagesize: 4
      &#125;,
      total: 0,
      pagesizes: [1, 2, 3, 4, 5, 6, 6, 7, 8]
    &#125;
  &#125;,
  methods:&#123;
  	// 改变每页大小
    handleSizeChange (val) &#123;
      this.queryObj.pagesize = val
      this.getGoodsList()
    &#125;,
    // 改变当前页
    handleCurrentChange (val) &#123;
      this.queryObj.pagenum = val
      this.getGoodsList()
    &#125;
  &#125;
&#125;
&lt;/script&gt;</code></pre>

<h4 id="面包屑的二次封装"><a href="#面包屑的二次封装" class="headerlink" title="面包屑的二次封装"></a>面包屑的二次封装</h4><blockquote>
<p>在定义一个路由时，配置meta.title属性</p>
</blockquote>
<pre><code class="hljs javascript">&#123;
  <span class="hljs-attr">path</span>: <span class="hljs-string">&#x27;/add&#x27;</span>,
  <span class="hljs-attr">meta</span>: &#123;
    <span class="hljs-attr">titel1</span>: <span class="hljs-string">&#x27;商品管理&#x27;</span>,
    <span class="hljs-attr">titel2</span>: <span class="hljs-string">&#x27;添加商品&#x27;</span>
  &#125;,
  <span class="hljs-attr">component</span>: Add
&#125;</code></pre>
<pre><code class="hljs vue">&lt;template&gt;
  &lt;el-breadcrumb separator-class=&quot;el-icon-arrow-right&quot;&gt;
    &lt;el-breadcrumb-item to=&quot;home&quot;&gt;首页&lt;/el-breadcrumb-item&gt;
    &lt;el-breadcrumb-item v-for=&quot;(item,index) in label&quot; :key=&quot;index&quot;&gt;&#123;&#123;item&#125;&#125;&lt;/el-breadcrumb-item&gt;
  &lt;/el-breadcrumb&gt;
&lt;/template&gt;

&lt;script&gt;
export default &#123;
  name: &#x27;Breadcrumb&#x27;,
  data () &#123;
    return &#123;
      label: []
    &#125;
  &#125;,
  created () &#123;
    this.$route.matched.forEach(el =&gt; &#123;
      if (el.path !== &#x27;/home&#x27;) &#123;
        this.label.push(el.meta.titel1)
        this.label.push(el.meta.titel2)
      &#125;
    &#125;)
  &#125;
&#125;
&lt;/script&gt;

&lt;style lang=&quot;less&quot; scoped&gt;
.el-breadcrumb&#123;
  margin-bottom: 20px;
&#125;
&lt;/style&gt;</code></pre>

<h4 id="el-form的二次封装"><a href="#el-form的二次封装" class="headerlink" title="el-form的二次封装"></a>el-form的二次封装</h4><ul>
<li>由于这项目很多地方都用到表单，为了提高代码的复用性，决定对el-form进行封装</li>
<li>由于每个输入元素的类型不同，在formConfig表单配置文件中定义一个type属性，根据type的不同，结合v-if，来渲染不同的输入元素</li>
<li>用v-for循环每个输入元素，注意el-form-item的prop一定要填，不然无法调用表单验证规则</li>
</ul>
<blockquote>
<p>封装</p>
</blockquote>
<pre><code class="hljs vue">&lt;template&gt;
  &lt;el-form :model=&quot;form&quot; ref=&quot;form&quot; :rules=&quot;rules&quot; label-width=&quot;80px&quot; :inline=&quot;false&quot; size=&quot;normal&quot; status-icon&gt;
    &lt;el-form-item v-for=&quot;(item,index) in formConfig&quot;  :key=&quot;index&quot; :label=&quot;item.label&quot; :prop=&quot;item.prop&quot;&gt;
      &lt;!-- 普通输入框 --&gt;
      &lt;el-input
        v-if=&quot;item.type===&#x27;input&#x27;&quot;
        v-model=&quot;form[item.prop]&quot;
        :disabled=&quot;item.disabled&quot;
        :placeholder=&quot;&#x27;请输入&#x27;+item.label&quot;
      &gt;
      &lt;/el-input&gt;
      &lt;!-- 数字类型的输入框 --&gt;
      &lt;el-input
        v-if=&quot;item.type===&#x27;inputAndNunber&#x27;&quot;
        v-model.number=&quot;form[item.prop]&quot;
        :disabled=&quot;item.disabled&quot;
        :placeholder=&quot;&#x27;请输入&#x27;+item.label&quot;
      &gt;
      &lt;/el-input&gt;
      &lt;!-- 单选框 --&gt;
      &lt;el-radio-group v-if=&quot;item.type===&#x27;radio&#x27;&quot; v-model=&quot;form[item.prop]&quot;&gt;
        &lt;el-radio v-for=&quot;(i,index) in item.children&quot; :key=&quot;index&quot; :label=&quot;i.label&quot; :disabled=&quot;i.disabled&quot;&gt;
          &#123;&#123;i.title&#125;&#125;
        &lt;/el-radio&gt;
      &lt;/el-radio-group&gt;
      &lt;!-- 多选框 --&gt;
      &lt;el-checkbox-group v-if=&quot;item.type===&#x27;checkbox&#x27;&quot; v-model=&quot;form[item.prop]&quot;&gt;
        &lt;el-checkbox v-for=&quot;(i,index) in item.children&quot; :key=&quot;index&quot; :label=&quot;i.label&quot; :disabled=&quot;i.disabled&quot;&gt;
          &#123;&#123;i.title&#125;&#125;
        &lt;/el-checkbox&gt;
      &lt;/el-checkbox-group&gt;
      &lt;!-- 选择器 --&gt;
      &lt;el-select v-if=&quot;item.type===&#x27;select&#x27;&quot; v-model=&quot;form[item.prop]&quot; placeholder=&quot;请选择&quot;&gt;
        &lt;el-option v-for=&quot;(i,index) in item.children&quot;
          :key=&quot;index&quot;
          :label=&quot;i.label&quot;
          :value=&quot;i.value&quot;&gt;
        &lt;/el-option&gt;
      &lt;/el-select&gt;
      &lt;!-- 日期选择器 --&gt;
      &lt;el-date-picker v-if=&quot;item.type===&#x27;date&#x27;&quot; v-model=&quot;form[item.prop]&quot; type=&quot;date&quot; size=&quot;normal&quot; placeholder=&quot;选择日期时间&quot;&gt;
      &lt;/el-date-picker&gt;
    &lt;/el-form-item&gt;
    &lt;slot name=&quot;submitAndCancel&quot;&gt;&lt;/slot&gt;
  &lt;/el-form&gt;

&lt;/template&gt;

&lt;script&gt;
export default &#123;
  name: &#x27;FromNew&#x27;,
  props: &#123;
    form: Object,
    formConfig: Array,
    rules: Object
  &#125;
&#125;
&lt;/script&gt;

&lt;style&gt;

&lt;/style&gt;
</code></pre>

<blockquote>
<p>调用</p>
</blockquote>
<pre><code class="hljs vue">&lt;template&gt;
  &lt;FromNew
    :form=&quot;form&quot;
    :formConfig=&quot;formConfig&quot;
    :rules=&quot;rules&quot;
    ref=&quot;myFromNew&quot;
  &gt;
    &lt;template #submitAndCancel&gt;
      &lt;div&gt;
        &lt;el-button size=&quot;default&quot; @click=&quot;reset&quot;&gt;重置&lt;/el-button&gt;
        &lt;el-button type=&quot;primary&quot; size=&quot;default&quot; @click=&quot;next&quot;&gt;确定        &lt;/el-button&gt;
      &lt;/div&gt;
    &lt;/template&gt;
  &lt;/FromNew&gt;
&lt;/template&gt;

&lt;script&gt;
export default &#123;
  name: &#x27;调用者&#x27;,
  data() &#123;
    return &#123;
      form: &#123;
        goods_name: &#x27;&#x27;,
        goods_price: &#x27;&#x27;,
        goods_weight: &#x27;&#x27;,
        goods_number: &#x27;&#x27;,
        sex: &#x27;&#x27;,
        sport: [],
        city: &#x27;&#x27;,
        date: &#x27;&#x27;
      &#125;,
      formConfig: [
        &#123;
          type: &#x27;input&#x27;,
          prop: &#x27;goods_name&#x27;,
          label: &#x27;商品名称&#x27;
        &#125;,
        &#123;
          type: &#x27;inputAndNunber&#x27;,
          prop: &#x27;goods_price&#x27;,
          label: &#x27;商品价格&#x27;
        &#125;,
        &#123;
          type: &#x27;inputAndNunber&#x27;,
          prop: &#x27;goods_weight&#x27;,
          label: &#x27;商品重量&#x27;
        &#125;,
        &#123;
          type: &#x27;inputAndNunber&#x27;,
          prop: &#x27;goods_number&#x27;,
          label: &#x27;商品数量&#x27;
        &#125;,
        &#123;
          type: &#x27;radio&#x27;,
          prop: &#x27;sex&#x27;,
          children: [
            &#123;
              label: &#x27;男&#x27;,
              title: &#x27;男&#x27;
            &#125;,
            &#123;
              label: &#x27;女&#x27;,
              title: &#x27;女&#x27;
            &#125;
          ]
        &#125;,
        &#123;
          type: &#x27;checkbox&#x27;,
          prop: &#x27;sport&#x27;,
          children: [
            &#123;
              label: &#x27;足球&#x27;,
              title: &#x27;足球&#x27;
            &#125;,
            &#123;
              label: &#x27;篮球&#x27;,
              title: &#x27;篮球&#x27;
            &#125;,
            &#123;
              label: &#x27;羽毛球&#x27;,
              title: &#x27;羽毛球&#x27;
            &#125;,
            &#123;
              label: &#x27;0&#x27;,
              title: &#x27;禁选&#x27;,
              disabled: true
            &#125;
          ]
        &#125;,
        &#123;
          type: &#x27;select&#x27;,
          prop: &#x27;city&#x27;,
          children: [
            &#123;
              value: &#x27;上海&#x27;,
              label: &#x27;上海&#x27;
            &#125;,
            &#123;
              value: &#x27;北京&#x27;,
              label: &#x27;北京&#x27;
            &#125;,
            &#123;
              value: &#x27;广州&#x27;,
              label: &#x27;广州&#x27;
            &#125;
          ]
        &#125;,
        &#123;
          type: &#x27;date&#x27;,
          prop: &#x27;date&#x27;
        &#125;
      ],
      rules: &#123;
        goods_name: [
          &#123; required: true, message: &#x27;请填写商品名称&#x27;, trriger: &#x27;blur&#x27; &#125;,
          &#123; min: 2, max: 10, message: &#x27;请输入2-10个字符&#x27;, trriger: &#x27;blur&#x27; &#125;
        ],
        goods_price: [
          &#123; required: true, validator: validateNumber, trriger: &#x27;blur&#x27; &#125;
        ],
        goods_weight: [
          &#123; required: true, validator: validateNumber, trriger: &#x27;blur&#x27; &#125;
        ],
        goods_number: [
          &#123; required: true, validator: validateNumber, trriger: &#x27;blur&#x27; &#125;
        ],
        sex: [
          &#123; required: true, message: &#x27;请选择性别&#x27;, trriger: &#x27;blur&#x27; &#125;
        ],
        sport: [
          &#123; type: &#x27;array&#x27;, required: true, message: &#x27;请选择爱好&#x27;, trriger: &#x27;blur&#x27; &#125;
        ],
        city: [
          &#123; required: true, message: &#x27;请选择城市&#x27;, trriger: &#x27;blur&#x27; &#125;
        ],
        date: [
          &#123; type: &#x27;date&#x27;, required: true, message: &#x27;请选择日期&#x27;, trriger: &#x27;blur&#x27; &#125;
        ]
      &#125;
    &#125;
  &#125;,
&#125;
&lt;/script&gt;</code></pre>

<h4 id="对话框中的表单封装"><a href="#对话框中的表单封装" class="headerlink" title="对话框中的表单封装"></a>对话框中的表单封装</h4><pre><code class="hljs javascript"><span class="hljs-comment">// 绑定的数据</span>
<span class="hljs-keyword">const</span> form=&#123;
	<span class="hljs-attr">username</span>:<span class="hljs-string">&#x27;&#x27;</span>,
	<span class="hljs-attr">password</span>:<span class="hljs-string">&#x27;&#x27;</span>,
	<span class="hljs-attr">email</span>:<span class="hljs-string">&#x27;&#x27;</span>,
	<span class="hljs-attr">mobile</span>:<span class="hljs-string">&#x27;&#x27;</span>
&#125;
<span class="hljs-comment">// 表单配置文件</span>
<span class="hljs-keyword">const</span> formlabel=[
	&#123;
		<span class="hljs-attr">prop</span>:<span class="hljs-string">&#x27;username&#x27;</span>,
		<span class="hljs-attr">label</span>:<span class="hljs-string">&#x27;用户名&#x27;</span>,
		<span class="hljs-attr">type</span>:<span class="hljs-string">&#x27;input&#x27;</span>,
		<span class="hljs-attr">disabled</span>:<span class="hljs-literal">true</span>
	&#125;,
	&#123;
		<span class="hljs-attr">prop</span>:<span class="hljs-string">&#x27;password&#x27;</span>,
		<span class="hljs-attr">label</span>:<span class="hljs-string">&#x27;密码&#x27;</span>,
		<span class="hljs-attr">type</span>:<span class="hljs-string">&#x27;text&#x27;</span>
	&#125;,
	&#123;
		<span class="hljs-attr">prop</span>:<span class="hljs-string">&#x27;email&#x27;</span>,
		<span class="hljs-attr">label</span>:<span class="hljs-string">&#x27;邮箱&#x27;</span>,
		<span class="hljs-attr">type</span>:<span class="hljs-string">&#x27;email&#x27;</span>
	&#125;,
	&#123;
		<span class="hljs-attr">prop</span>:<span class="hljs-string">&#x27;mobile&#x27;</span>,
		<span class="hljs-attr">label</span>:<span class="hljs-string">&#x27;电话&#x27;</span>,
		<span class="hljs-attr">type</span>:<span class="hljs-string">&#x27;tel&#x27;</span>
	&#125;,
]</code></pre>
<ul>
<li>model 表单绑定的数据对象</li>
<li>输入框绑定 from[item.prop]<pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">el-form</span> </span>
<span class="hljs-tag">  <span class="hljs-attr">:model</span>=<span class="hljs-string">&quot;form&quot;</span></span>
<span class="hljs-tag">  <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;form&quot;</span>	</span>
<span class="hljs-tag">  <span class="hljs-attr">status-icon</span> </span>
<span class="hljs-tag">  <span class="hljs-attr">:rules</span>=<span class="hljs-string">&quot;rules&quot;</span> </span>
<span class="hljs-tag">  <span class="hljs-attr">label-width</span>=<span class="hljs-string">&quot;80px&quot;</span> </span>
<span class="hljs-tag">  <span class="hljs-attr">:inline</span>=<span class="hljs-string">&quot;false&quot;</span> </span>
<span class="hljs-tag">  <span class="hljs-attr">size</span>=<span class="hljs-string">&quot;normal&quot;</span></span>
<span class="hljs-tag">&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">el-form-item</span></span>
<span class="hljs-tag">    <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(item,index) in formLabel&quot;</span></span>
<span class="hljs-tag">    <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span> <span class="hljs-attr">:label</span>=<span class="hljs-string">&quot;item.label&quot;</span></span>
<span class="hljs-tag">    <span class="hljs-attr">:prop</span>=<span class="hljs-string">&quot;item.prop&quot;</span></span>
<span class="hljs-tag">  &gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-input</span></span>
<span class="hljs-tag">      <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;form[item.prop]&quot;</span></span>
<span class="hljs-tag">      <span class="hljs-attr">:placeholder</span>=<span class="hljs-string">&quot;&#x27;请输入&#x27;+item.label&quot;</span></span>
<span class="hljs-tag">      <span class="hljs-attr">:disabled</span>=<span class="hljs-string">&quot;item.disabled&quot;</span></span>
<span class="hljs-tag">    &gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">el-input</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">el-form-item</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">el-form-item</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;addUserInfo&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;cancel&quot;</span>&gt;</span>取消<span class="hljs-tag">&lt;/<span class="hljs-name">el-button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;primary&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;addUserInfo&quot;</span>&gt;</span>确定<span class="hljs-tag">&lt;/<span class="hljs-name">el-button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">el-form-item</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">el-form-item</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;editUserInfo&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;cancel&quot;</span>&gt;</span>取消<span class="hljs-tag">&lt;/<span class="hljs-name">el-button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;primary&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;editUserInfo&quot;</span>&gt;</span>确定<span class="hljs-tag">&lt;/<span class="hljs-name">el-button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">el-form-item</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">el-form</span>&gt;</span></code></pre></li>
</ul>
<h4 id="角色列表的树形控件"><a href="#角色列表的树形控件" class="headerlink" title="角色列表的树形控件"></a>角色列表的树形控件</h4><blockquote>
<p>data 展示数据<br>props 内置label和children，指定data中的字段<br>node-key绑定id很需要<br>default-checked-keys 默认选中的节点</p>
</blockquote>
<pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">el-tree</span></span>
<span class="hljs-tag">    <span class="hljs-attr">:data</span>=<span class="hljs-string">&quot;authList&quot;</span></span>
<span class="hljs-tag">    <span class="hljs-attr">:props</span>=<span class="hljs-string">&quot;AssignProps&quot;</span></span>
<span class="hljs-tag">    <span class="hljs-attr">show-checkbox</span></span>
<span class="hljs-tag">    <span class="hljs-attr">node-key</span>=<span class="hljs-string">&quot;id&quot;</span></span>
<span class="hljs-tag">    <span class="hljs-attr">default-expand-all</span></span>
<span class="hljs-tag">    <span class="hljs-attr">:default-checked-keys</span>=<span class="hljs-string">&quot;defKeys&quot;</span></span>
<span class="hljs-tag">&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">el-tree</span>&gt;</span></code></pre>

<h2 id="路由组件架构"><a href="#路由组件架构" class="headerlink" title="路由组件架构"></a>路由组件架构</h2><ul>
<li>项目分登录和主页两个部分</li>
<li>主页布局除主体不同，其余一样</li>
<li>路由和组件使用嵌套，架构如下：<pre><code class="hljs html"><span class="hljs-comment">&lt;!-- app --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;app&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">router-view</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-comment">&lt;!-- home --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">el-container</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&#x27;home&#x27;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-header</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">el-header</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">el-container</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">el-aside</span> <span class="hljs-attr">width</span>=<span class="hljs-string">&quot;auto&quot;</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">el-aside</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">el-main</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">router-view</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">el-main</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">el-container</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">el-container</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span></code></pre></li>
</ul>
<pre><code class="hljs javascript"><span class="hljs-keyword">const</span> routes=[
	&#123;
		<span class="hljs-attr">path</span>:<span class="hljs-string">&#x27;/&#x27;</span>,
		<span class="hljs-attr">redirect</span>:<span class="hljs-string">&#x27;/login&#x27;</span>
	&#125;,
	&#123;
		<span class="hljs-attr">path</span>:<span class="hljs-string">&#x27;/login&#x27;</span>,
		<span class="hljs-attr">component</span>:Login
	&#125;,
	&#123;
		<span class="hljs-attr">path</span>:<span class="hljs-string">&#x27;/home&#x27;</span>,
		<span class="hljs-attr">component</span>:Home,
		<span class="hljs-attr">redirect</span>:<span class="hljs-string">&#x27;/users&#x27;</span>	<span class="hljs-comment">//只有重定向到子视图，才能进入子router-view</span>
		<span class="hljs-attr">children</span>:[
			&#123;
				<span class="hljs-attr">path</span>:<span class="hljs-string">&#x27;/users&#x27;</span>,
				<span class="hljs-attr">component</span>:Users,
			&#125;,
			&#123;
				<span class="hljs-attr">path</span>:<span class="hljs-string">&#x27;/roles&#x27;</span>,
				<span class="hljs-attr">component</span>:Roles,
			&#125;
		]
	&#125;,
]</code></pre>

<h2 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h2><h4 id="git命令实现对版本进行控制，将本地代码上传至gitee"><a href="#git命令实现对版本进行控制，将本地代码上传至gitee" class="headerlink" title="git命令实现对版本进行控制，将本地代码上传至gitee"></a>git命令实现对版本进行控制，将本地代码上传至gitee</h4><ul>
<li>git branch 查看当前分支</li>
<li>git checkout xx 切换到xx分支</li>
<li>git checkout -b xx 创建xx分支并切换到该分支</li>
<li>git status 查看文件状态</li>
<li>git add . 将所有文件添加到暂缓区</li>
<li>git commit -m “xxx” 将暂缓区的文件提交到本地仓库</li>
<li>git push -u origin xx 在gitee创建xx分支，并将本地仓库的所有文件上传到该分支</li>
<li>git merge xx 将xx分支合并到当前分支</li>
</ul>
<h4 id="axios的两种传参形式"><a href="#axios的两种传参形式" class="headerlink" title="axios的两种传参形式"></a>axios的两种传参形式</h4><blockquote>
<p>url传参</p>
</blockquote>
<ul>
<li><p>this.$http.get(‘/users?xx==xx’)</p>
<blockquote>
<p>对象传参</p>
</blockquote>
</li>
<li><p>this.$http.get(‘/users’, { params: this.queryObj })</p>
</li>
</ul>
<h4 id="树形表格：vue-table-with-tree-gird"><a href="#树形表格：vue-table-with-tree-gird" class="headerlink" title="树形表格：vue-table-with-tree-gird"></a>树形表格：vue-table-with-tree-gird</h4><blockquote>
<p>用法跟普通表格差不多，直接看<a target="_blank" rel="noopener" href="https://blog.csdn.net/gaogzhen/article/details/108090145">文档</a></p>
</blockquote>
<h4 id="权限管理业务分析"><a href="#权限管理业务分析" class="headerlink" title="权限管理业务分析"></a>权限管理业务分析</h4><blockquote>
<p>用户 分配 角色<br>角色 拥有 权限</p>
</blockquote>
<h4 id="el表格跟el表单"><a href="#el表格跟el表单" class="headerlink" title="el表格跟el表单"></a>el表格跟el表单</h4><blockquote>
<p>el表格</p>
</blockquote>
<ul>
<li>绑定一个数据源</li>
<li>如果有多列类型相同的，可以v-for遍历，并配置其表单<blockquote>
<p>el表单</p>
</blockquote>
</li>
<li>绑定一个数据对象</li>
<li>绑定验证规则</li>
</ul>
<h4 id="字符串-0-变为数字类型"><a href="#字符串-0-变为数字类型" class="headerlink" title="字符串-0 变为数字类型"></a>字符串-0 变为数字类型</h4><pre><code class="hljs javascript">v-model=<span class="hljs-string">&quot;str-0&quot;</span></code></pre>

<h4 id="商品列表-添加商品"><a href="#商品列表-添加商品" class="headerlink" title="商品列表/添加商品"></a>商品列表/添加商品</h4><ul>
<li>根据标签页的变化而改变步骤条的变化</li>
<li>每个标签页在切换之前，先进行预验证，通过el-tags的before-leave属性</li>
<li>before-leave在标签离开之前的钩子</li>
</ul>
<h4 id="深拷贝和浅拷贝的区别"><a href="#深拷贝和浅拷贝的区别" class="headerlink" title="深拷贝和浅拷贝的区别"></a>深拷贝和浅拷贝的区别</h4><ul>
<li>深拷贝是直接赋值一个对象的实体而不是引用</li>
<li>深拷贝不随着原对象的变化而变化</li>
<li>深拷贝我选择是<a target="_blank" rel="noopener" href="https://www.lodashjs.com/">lodash</a>javascript的一个工具库中cloneDeep</li>
</ul>
<blockquote>
<p>快速使用</p>
</blockquote>
<pre><code class="hljs javascript"><span class="hljs-keyword">import</span> _ <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;lodash&#x27;</span>
<span class="hljs-keyword">var</span> obj=&#123;
	<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;lodash&#x27;</span>
&#125;
<span class="hljs-keyword">var</span> newobj=_.cloneDeep(obj)</code></pre>

<h2 id="项目优化"><a href="#项目优化" class="headerlink" title="项目优化"></a>项目优化</h2><blockquote>
<p>策略</p>
</blockquote>
<ul>
<li>生成打包报告</li>
<li>第三方启用cdn</li>
<li>element-ui按需加载</li>
<li>路由懒加载</li>
<li>首页内容定制</li>
<li>nprogress 显示进度条的一个包</li>
</ul>

    </div>
     
    <div class="post-footer__meta"><p>更新于 2022-04-30</p></div> 
    <div class="post-entry__tags"><a href="/tags/%E7%94%B5%E5%95%86/" class="post-tags__link button"># 电商</a><a href="/tags/%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86/" class="post-tags__link button"># 后台管理</a></div> 
</article>


    <div class="nav">
        <div class="nav__prev">
            
                <a href="/2022/05/06/nodejs%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" class="nav__link">
                    <div>
                        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M589.088 790.624L310.464 512l278.624-278.624 45.248 45.248L400.96 512l233.376 233.376z" fill="#808080"></path></svg>
                    </div>
                    <div>
                        <div class="nav__label">
                            <!-- Previous Post -->
                            上一页
                        </div>
                        <div class="nav__title">
                            nodeJs学习笔记
                        </div>
                    </div>
                </a>
            
        </div>
        <div class="nav__next">
            
                <a href="/2022/04/12/%E7%BB%84%E4%BB%B6%E9%97%B4%E9%80%9A%E4%BF%A1/" class="nav__link">
                    <div>
                        <div class="nav__label">
                            <!-- Next Post -->
                            下一页
                        </div>
                        <div class="nav__title">
                            组件间通信
                        </div>
                    </div>
                    <div>
                        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M434.944 790.624l-45.248-45.248L623.04 512l-233.376-233.376 45.248-45.248L713.568 512z" fill="#808080"></path></svg>
                    </div>
                </a>
            
        </div>
    </div>



    <div class="post__comments content-card" id="comment">
        
    <h4>评论</h4>
    
    
    
    <div id="valine_container" class="valine_thread"></div>

    
    
    
    
    
    
    
    


    </div>



</main>

            <footer class="footer" style="font-size: 10px;">
     
    <a href="#" class="button" id="b2t" aria-label="回到顶部" title="回到顶部">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="32" height="32">
            <path d="M233.376 722.752L278.624 768 512 534.624 745.376 768l45.248-45.248L512 444.128zM192 352h640V288H192z" fill="currentColor"></path>
        </svg>
    </a>

    


    
    
    
        <span id="busuanzi_container_site_uv" hidden>
            <span>游客:</span>
            <span id="busuanzi_value_site_uv"></span>
            <span></span>
            
                <span> </span>
            
        </span>
    
    
        <span id="busuanzi_container_site_pv" hidden>
            <span>次数:</span>
            <span id="busuanzi_value_site_pv"></span>
            <span></span>
            
        </span>
    
 
 

 
    
    
    <p>
        <!-- Powered by <a href="https://hexo.io" target="_blank">Hexo</a> | Theme - <a href="https://github.com/ChrAlpha/hexo-theme-cards" target="_blank">Cards</a> -->
        <span style="color: black;">作者：张程</span>
    </p>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
    </script>
    <script>
        var a_idx = 0;
            jQuery(document).ready(function($) {
                $("body").click(function(e) {
                    var a = new Array("会当凌绝顶，一览众山小", "春蚕到死丝方尽，蜡炬成灰泪始干", "夕阳无限好，只是近黄昏",
                     "位卑未敢忘忧国", "纸上得来终觉浅，绝知此事要躬行", "人生自古谁无死，留取丹心照汗青", "山重水复疑无路，柳暗花明又一村" ,
                     "小荷才露尖尖角，早有蜻蜓立上头", "床前明月光，疑是地上霜", "春色满园关不住，一枝红杏出墙来", 
                     "山际见来烟，竹中窥落日", "道狭草木长，夕露沾我衣","天长地久有时尽，此恨绵绵无绝期");
                    var color = new Array("#7B7B7B", "#CE0000", "#FF0080","#E800E8","#921AFF","#2828FF",
                    "#0072E3","#00CACA","#02DF82","#00DB00","#8CEA00","#E1E100","#EAC100","#F75000"
                    ,"#B87070","#AFAF61","#6FB7B7","#9999CC","#B766AD");
                    var $i = $("<a href='#' style='text-decoration:none'/>").text(a[a_idx]);
                    a_idx = (a_idx + 1) % a.length;
                    var x = e.pageX,
                        y = e.pageY;
                    $i.css({
                        "z-index": 999999999999999999999999999999999999999999999999999999999999999999999,
                        "top": y - 20,
                        "left": x,
                        "position": "absolute",
                        "font-weight": "bold",
                        "color": color[Math.floor(Math.random()*color.length)]
                    });
                    $("body").append($i);
                    $i.animate({
                            "top": y - 180,
                            "opacity": 0
                        },
                        1500,
                        function() {
                            $i.remove();
                        });
                });
            });
        </script>
    <script>
        !function() {
            function o(w, v, i) {
                return w.getAttribute(v) || i
            }
            function j(i) {
                return document.getElementsByTagName(i)
            }
            function l() {
                var i = j("script"),
                w = i.length,
                v = i[w - 1];
                return {
                    l: w,
                    z: o(v, "zIndex", -1),
                    o: o(v, "opacity", 0.5),
                    c: o(v, "color", "0,0,0"),
                    n: o(v, "count", 99)
                }
            }
            function k() {
                r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
                n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
            }
            function b() {
                e.clearRect(0, 0, r, n);
                var w = [f].concat(t);
                var x, v, A, B, z, y;
                t.forEach(function(i) {
                    i.x += i.xa,
                    i.y += i.ya,
                    i.xa *= i.x > r || i.x < 0 ? -1 : 1,
                    i.ya *= i.y > n || i.y < 0 ? -1 : 1,
                    e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1);
                    for (v = 0; v < w.length; v++) {
                        x = w[v];
                        if (i !== x && null !== x.x && null !== x.y) {
                            B = i.x - x.x,
                            z = i.y - x.y,
                            y = B * B + z * z;
                            y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B, i.y -= 0.03 * z), A = (x.max - y) / x.max, e.beginPath(), e.lineWidth = A / 2, e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")", e.moveTo(i.x, i.y), e.lineTo(x.x, x.y), e.stroke())
                        }
                    }
                    w.splice(w.indexOf(i), 1)
                }),
                m(b)
            }
            var u = document.createElement("canvas"),
            s = l(),
            c = "c_n" + s.l,
            e = u.getContext("2d"),
            r,
            n,
            m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
            function(i) {
                window.setTimeout(i, 1000 / 45)
            },
            a = Math.random,
            f = {
                x: null,
                y: null,
                max: 20000
            };
            u.id = c;
            u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o;
            j("body")[0].appendChild(u);
            k(),
            window.onresize = k;
            window.onmousemove = function(i) {
                i = i || window.event,
                f.x = i.clientX,
                f.y = i.clientY
            },
            window.onmouseout = function() {
                f.x = null,
                f.y = null
            };
            for (var t = [], p = 0; s.n > p; p++) {
                var h = a() * r,
                g = a() * n,
                q = 2 * a() - 1,
                d = 2 * a() - 1;
                t.push({
                    x: h,
                    y: g,
                    xa: q,
                    ya: d,
                    max: 6000
                })
            }
            setTimeout(function() {
                b()
            }, 100)
    } ();
    </script>
</footer>

        </div>
        
    <script defer src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.1.0/dist/lazyload.min.js"></script>
    <script>
        window.lazyLoadOptions = {
            elements_selector: ".lazy",
            threshold: 0
        };
    </script>
 

 

 

 

 



 



 


    
 


    
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>

    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.4.1/dist/jquery.fancybox.min.css">

    
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.4.1/dist/jquery.fancybox.min.js"></script>

    <script>
        let lazyloadT = Boolean('true'),
            auto_fancybox = Boolean('false')
        if (auto_fancybox) {
            $(".post__content").find('img').each(function () {
                var element = document.createElement("a");
                $(element).attr("data-fancybox", "gallery");
                $(element).attr("href", $(this).attr("src"));
                if (lazyloadT) {
                    $(element).attr("href", $(this).attr("data-srcset"));
                }
                $(this).wrap(element);
            });
        } else {
            $(".post__content").find("fancybox").find('img').each(function () {
                var element = document.createElement("a");
                $(element).attr("data-fancybox", "gallery");
                $(element).attr("href", $(this).attr("src"));
                if (lazyloadT) {
                    $(element).attr("href", $(this).attr("data-srcset"));
                }
                $(this).wrap(element);
            });
        }
    </script>
 

 

 

 

 


    

    
    
    
    <script>
        function loadComment() {
            let e;
            (e = document.createElement("script")).src = 'https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js',
            document.body.appendChild(e);
            e.onload = () => {
                var valineConfig = {"appId":"c21JqSBfScFdueO44Scwp9Ba-gzGzoHsz","appKey":"apETP0QIekHzRXjTHvOnrQmS","placeholder":null,"path":null,"avatar":"retro","meta":["nick","mail","link"],"pageSize":null,"lang":null,"visitor":null,"highlight":null,"avatarForce":null,"recordIP":null,"serverURLs":null,"enableQQ":true,"requiredFields":["nick","mail"],"emojiCDN":null,"emojiMaps":null};
                valineConfig.el = '#valine_container';
                for (var i in valineConfig) {
                    if (valineConfig[i] === null) delete valineConfig[i];
                }
                new Valine(valineConfig);
            };
        }
    
        var runningOnBrowser = typeof window !== "undefined";
        var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro|msn)bot|crawl|spider|yand|duckgo/i.test(navigator.userAgent);
        var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window;
    
        setTimeout(function () {
            if (!isBot && supportsIntersectionObserver) {
                var comment_observer = new IntersectionObserver(function(entries) {
                    if (entries[0].isIntersecting) {
                        loadComment();
                        comment_observer.disconnect();
                    }
                }, { threshold: [0] });
                comment_observer.observe(document.getElementById('comment'));
            } else {
                loadComment();
            }
        }, 1);
    </script>


    
    
    
    
    

    
    
    
    
    

    
    
    



    </body>
</html>
